package com.lalameow.smithing.recipe;

import com.lalameow.common.exception.LaLaMeowException;
import com.lalameow.common.message.LaLaMeowMessage;
import com.lalameow.smithing.Smithing;
import com.lalameow.smithing.config.ConfigManager;
import com.lalameow.smithing.entity.EquimentEntity;
import com.lalameow.smithing.entity.FuelItemEntity;
import com.lalameow.smithing.util.Constans;
import com.lalameow.smithing.util.PluginUtils;
import com.lalameow.smithing.util.ProbabilityUtil;
import me.dpohvar.powernbt.api.NBTCompound;
import me.dpohvar.powernbt.api.NBTManager;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.text.MessageFormat;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * 创建人: 陈刚
 * 日期: 2017/3/4
 * 时间: 3:23
 * 功能：请进行修改
 */
public class ForgeItem  {

    public static ItemStack forge(String fuelItem, ItemStack forgeItem, Player player) throws LaLaMeowException {
        if(forgeItem==null){
            throw new LaLaMeowException("锻造的装备不能为空");
        }
        ItemMeta itemMeta=forgeItem.getItemMeta();
        if(itemMeta==null){
            throw new LaLaMeowException("此物品不支持锻造！");
        }
        String eqName=itemMeta.getDisplayName();
        if(eqName==null){
            throw new LaLaMeowException("此物品不支持锻造！");
        }
        EquimentEntity equimentEntity= ConfigManager.equimentMap.get(ChatColor.stripColor(eqName));
        FuelItemEntity fuelItemEntity= ConfigManager.fuelItemMap.get(ChatColor.stripColor(fuelItem));
        if(equimentEntity==null){
            throw new LaLaMeowException("物品"+eqName+"物品不存在与装备库中，请仔细检查你的装备库！");
        }else  if(fuelItemEntity==null){
            throw new LaLaMeowException("物品"+fuelItem+"不是一个有效的锻造石，请仔细检查你的锻造石库！");
        }

        switch (fuelItemEntity.getOperType()){
            case ADDNBT:
                if(addNBTNode(forgeItem,fuelItemEntity)){
                    LaLaMeowMessage.sendSuccess(player,"装备成功添加属性，请迅速去熔炉拿取！");
                }else {
                    LaLaMeowMessage.sendError(player, "锻造失败，再接再厉。！");
                }
               break;
            case DELNBT:
                removeNBTNode(forgeItem,fuelItemEntity);
                LaLaMeowMessage.sendSuccess(player,"成功移除装备属性，请迅速去熔炉拿取！");
                break;
            case UPGRADE:
                if(!equimentEntity.getUpgradeFuel().equals(fuelItemEntity.getFuelItemName())){
                    throw new LaLaMeowException("锻造装备不匹配，请检查你的装备！");
                }
                forgeItem=upgradeEqment(forgeItem,equimentEntity,fuelItemEntity,player);
                break;
            case ADDHOLE:
                forgeItem=holeEqment(forgeItem,equimentEntity,fuelItemEntity,player);
                break;
            case STRENGTHEN:
                forgeItem=strengthenEqment(forgeItem,equimentEntity,fuelItemEntity,player);
                break;
            case INLAY:
                forgeItem=inlayEqment(forgeItem,equimentEntity,fuelItemEntity,player);
                break;
            default:
                throw new LaLaMeowException("锻造石"+fuelItem+"操作类型(operType)未定义，请检查你的配置文件！");
        }

        equimentEntity= ConfigManager.equimentMap.get(ChatColor.stripColor(forgeItem.getItemMeta().getDisplayName()));
        return PluginUtils.updateDzLoreInfo(forgeItem,equimentEntity,fuelItemEntity);
    }

    /**
     * 镶嵌宝石
     * @param forgeItem
     * @param equimentEntity
     * @param fuelItemEntity
     * @param player
     * @return
     */
    private static ItemStack inlayEqment(ItemStack forgeItem, EquimentEntity equimentEntity, FuelItemEntity fuelItemEntity, Player player) throws LaLaMeowException {
        ItemMeta itemMeta=forgeItem.getItemMeta();
        List<String> loreList=itemMeta.getLore();
        int inlayCount= PluginUtils.getNoEmptyHole(loreList);
        double rate= ProbabilityUtil.calRate(fuelItemEntity.getRate(), fuelItemEntity.getRateDM(), inlayCount);
        if(ProbabilityUtil.isSucess(rate)){
            String holelable= ConfigManager.mainConfig.getHolelable();
            String holeemlable= ConfigManager.mainConfig.getHoleemlable();
            for(int i=0;i<loreList.size();i++){
                if(loreList.get(i).contains(holelable)&&loreList.get(i).contains(holeemlable)){
                    MessageFormat qhcsformat=new MessageFormat(ConfigManager.mainConfig.getInlylore());
                    String inlaylore=qhcsformat.format(new Object[]{holelable,fuelItemEntity.getFuelItemTranName(),fuelItemEntity.getNBTValue(),fuelItemEntity.getNBTLable()});
                    loreList.set(i,inlaylore);
                    if(player!=null)
                    sendMsgToPlayer(player, "&2装备镶嵌成功，装备附加宝石属性!");
                    break;
                }
            }
            itemMeta.setLore(loreList);
            forgeItem.setItemMeta(itemMeta);
            int inlay= PluginUtils.getNoEmptyHole(loreList);
            if(inlay==equimentEntity.getMaxhole()){
                PluginUtils.broadcast("&6[锻造工坊]&c恭喜某玩家成功把装备["+equimentEntity.getCusname()+"]&c镶嵌满了宝石！");
            }
        }else {
            sendMsgToPlayer(player, "&4装备镶嵌宝石失败!");
        }
       return forgeItem;
    }
    /**
     * 装备打孔
     * @param forgeItem
     * @param equimentEntity
     * @param fuelItemEntity
     * @param player
     * @return
     */
    private static ItemStack holeEqment(ItemStack forgeItem, EquimentEntity equimentEntity, FuelItemEntity fuelItemEntity, Player player){
        NBTCompound forgeItemNBT= NBTManager.nbtManager.read(forgeItem);
        int holeCount=forgeItemNBT.getInt(Constans.NBTHOLE);
        double rate= ProbabilityUtil.calRate(fuelItemEntity.getRate(),fuelItemEntity.getRateDM(),holeCount);
        if(ProbabilityUtil.isSucess(rate)){
            holeCount++;
            if(holeCount>=equimentEntity.getMaxhole()){
                holeCount=equimentEntity.getMaxhole();
            }
            forgeItemNBT.put(Constans.NBTHOLE, holeCount);
            NBTManager.nbtManager.write(forgeItem,forgeItemNBT);
            //所有孔开出来全服公告
            if(holeCount>=equimentEntity.getMaxhole()){
                PluginUtils.broadcast("&6[锻造工坊]&c恭喜某玩家成功把装备["+equimentEntity.getCusname()+"&c]开启了所有宝石孔！");
            }
            sendMsgToPlayer(player,"&2装备打孔成功,装备增加一个可镶嵌空槽!");
        }else{
            sendMsgToPlayer(player, "&4装备打孔失败!");
        }
        return forgeItem;
    }
    /**
     * 强化装备
     * @param forgeItem
     * @param equimentEntity
     * @param fuelItemEntity
     * @param player
     * @return
     */
    private static ItemStack strengthenEqment(ItemStack forgeItem, EquimentEntity equimentEntity, FuelItemEntity fuelItemEntity, Player player){
        NBTCompound forgeItemNBT=NBTManager.nbtManager.read(forgeItem);
        int strengthenCount=forgeItemNBT.getInt(Constans.NBTSTRENGTHEN);
        double rate= ProbabilityUtil.calRate(fuelItemEntity.getRate(),fuelItemEntity.getRateDM(),strengthenCount);
        if(ProbabilityUtil.isSucess(rate)){
            strengthenCount++;
            if(strengthenCount>=equimentEntity.getMaxStrengthen()){
                strengthenCount=equimentEntity.getMaxStrengthen();
            }
            forgeItemNBT.put(Constans.NBTSTRENGTHEN,strengthenCount);
            NBTManager.nbtManager.write(forgeItem,forgeItemNBT);
            //强化满级全服公告
            if(strengthenCount>=equimentEntity.getMaxStrengthen()){
                PluginUtils.broadcast("&6[锻造工坊]&c恭喜某玩家成功把装备["+equimentEntity.getCusname()+"&c]强化满级&b(+"+equimentEntity.getMaxStrengthen()+")&b！");
            }
            sendMsgToPlayer(player, "&2装备强化成功,装备属性增强!");
        }else{
            if(!castLvProtect(player)){
                strengthenCount--;
                if(strengthenCount<=0){
                    strengthenCount=0;
                }
                forgeItemNBT.put(Constans.NBTSTRENGTHEN,strengthenCount);
                NBTManager.nbtManager.write(forgeItem,forgeItemNBT);
                sendMsgToPlayer(player, "&4装备强化失败,装备属性削弱!");
            }else {
                sendMsgToPlayer(player, "&4装备强化失败！&2保护符生效，强化等级未降级。");
            }


        }
        return forgeItem;
    }
    /**
     * 锻造升级武器
     * @param forgeItem
     * @param equimentEntity
     * @param fuelItemEntity
     * @param player
     * @return
     * @throws LaLaMeowException
     */
    private static ItemStack upgradeEqment(ItemStack forgeItem, EquimentEntity equimentEntity, FuelItemEntity fuelItemEntity, Player player) throws LaLaMeowException {
        NBTCompound forgeItemNBT=NBTManager.nbtManager.read(forgeItem);
        int upcradeCount=forgeItemNBT.getInt(Constans.NBTUPGRADE);
        double rate= ProbabilityUtil.calRate(fuelItemEntity.getRate(),fuelItemEntity.getRateDM(),upcradeCount);
        if(ProbabilityUtil.isSucess(rate)){
            if(upcradeCount>=equimentEntity.getUpgradeCount()){
               EquimentEntity upgradeItemEntity= ConfigManager.equimentMap.get(equimentEntity.getUpgradeItemName());
               forgeItem=new ItemStack(Material.getMaterial(upgradeItemEntity.getId()));
               ItemMeta itemMeta=forgeItem.getItemMeta();
               itemMeta.setDisplayName(upgradeItemEntity.getEqumentTranName());
               itemMeta.setLore(PluginUtils.translateColorSignList(upgradeItemEntity.getLore()));
               forgeItem.setItemMeta(itemMeta);
               sendMsgToPlayer(player,"&2装备锻造成功!已达到装备锻造等级,装备进化成功,属性大幅度提升!");
               //进化成功全服公告
               PluginUtils.broadcast("&6[锻造工坊]&c恭喜某玩家成功把装备["+equimentEntity.getCusname()+"&c]进化为["+upgradeItemEntity.getEqumentTranName()+"&c]！");
            }else{
                upcradeCount++;
                forgeItemNBT.put(Constans.NBTUPGRADE,upcradeCount);
                NBTManager.nbtManager.write(forgeItem,forgeItemNBT);
                sendMsgToPlayer(player,"&2锻造成功!装备锻造等级增加1.当前等级为:"+upcradeCount+"/"+equimentEntity.getUpgradeCount()+"");
            }
        }else{
            if(!castLvProtect(player)){
                upcradeCount--;
                if(upcradeCount<=0){
                    upcradeCount=0;
                }
                forgeItemNBT.put(Constans.NBTUPGRADE,upcradeCount);
                NBTManager.nbtManager.write(forgeItem,forgeItemNBT);
                sendMsgToPlayer(player,"&4锻造失败!装备锻造等级减1.当前等级为:"+upcradeCount+"/"+equimentEntity.getUpgradeCount()+"");
            }else {
                sendMsgToPlayer(player,"&4锻造失败!保护符生效，等级未减少.当前等级为:"+upcradeCount+"/"+equimentEntity.getUpgradeCount()+"");
            }


        }
        return forgeItem;
    }
    /**
     * 移除武器的某个NBT节点
     * @param forgeItem
     * @param fuelItemEntity
     */
    private static void removeNBTNode(ItemStack forgeItem, FuelItemEntity fuelItemEntity){
        NBTCompound nbtCompound=NBTManager.nbtManager.read(forgeItem);
        if(nbtCompound!=null){
            nbtCompound.remove(fuelItemEntity.getNBTLable());
            NBTManager.nbtManager.write(forgeItem,nbtCompound);
        }
    }

    /**
     * 给武器添加某个NBT节点
     * @param forgeItem
     * @param fuelItemEntity
     * @return
     */
    private static boolean addNBTNode(ItemStack forgeItem, FuelItemEntity fuelItemEntity){
        NBTCompound nbtCompound=NBTManager.nbtManager.read(forgeItem);
        if(nbtCompound==null){
            nbtCompound=new NBTCompound();
        }

        if(ProbabilityUtil.isSucess(fuelItemEntity.getRate())){
            if(fuelItemEntity.getNBTValue() instanceof String){
                nbtCompound.put(fuelItemEntity.getNBTLable(), PluginUtils.getType(fuelItemEntity.getNBTType(),fuelItemEntity.getNBTValue()));
            }
            NBTManager.nbtManager.write(forgeItem,nbtCompound);
            return true;
        }else{
            return false;
        }
    }

    /**
     * 检查是否有保护符
     * @param player
     * @return
     */
    private static boolean castLvProtect(Player player){
        if(player==null){return false;}
        if(!player.isOnline()){return false;}
        for (ItemStack itemStack : player.getInventory().getContents()) {
            if(itemStack!=null){
                ItemMeta itemMeta=itemStack.getItemMeta();
                if(itemMeta!=null){
                    if(ConfigManager.mainConfig.getKeeplvname().equals(itemMeta.getDisplayName())){
                       if(itemStack.getAmount()-1<=0){
                           player.getInventory().removeItem(itemStack);
                    }else{
                        itemStack.setAmount(itemStack.getAmount()-1);
                    }

                       return true;
                    }
                }
            }
        }
        return false;
    }
    private static void sendMsgToPlayer(Player player, String msg){
        if(player==null){return;}
        if(!player.isOnline()){return;}
        player.sendMessage(PluginUtils.translateColorSign(msg));

    }
}

